package com.srmt.document.feishu.internal.table.util;

import com.srmt.document.exception.TableException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Sheet坐标转换工具类
 * 提供Sheet相关的坐标转换、token解析等工具方法
 * 
 * @author srmt
 * @since 1.3.0
 */
public class SheetCoordinateHelper {
    
    private static final Logger logger = LoggerFactory.getLogger(SheetCoordinateHelper.class);
    
    /**
     * 解析sheet token
     * token格式可能是：
     * 1. 单独的spreadsheetToken（对于默认的第一个sheet）
     * 2. spreadsheetToken_sheetId格式
     * 
     * @param token 完整的token字符串
     * @return [spreadsheetToken, sheetId]数组
     * @throws TableException 如果token格式不正确
     */
    public static String[] parseSheetToken(String token) throws TableException {
        if (token == null || token.isEmpty()) {
            throw new TableException("电子表格令牌为空");
        }
        
        // 查找最后一个下划线的位置
        int lastUnderscoreIndex = token.lastIndexOf('_');
        
        if (lastUnderscoreIndex == -1) {
            // 没有下划线，整个token就是spreadsheetToken，sheetId为空（默认第一个sheet）
            return new String[]{token, ""};
        }
        
        if (lastUnderscoreIndex == 0 || lastUnderscoreIndex == token.length() - 1) {
            // 下划线在开头或结尾，格式不正确
            throw new TableException("无效 sheet token format: " + token);
        }
        
        String spreadsheetToken = token.substring(0, lastUnderscoreIndex);
        String sheetId = token.substring(lastUnderscoreIndex + 1);
        
        return new String[]{spreadsheetToken, sheetId};
    }
    
    /**
     * 构建范围字符串
     * 
     * @param sheetId 工作表ID
     * @param startRow 起始行（1-based）
     * @param startCol 起始列（1-based）
     * @param endRow 结束行（1-based）
     * @param endCol 结束列（1-based）
     * @return 范围字符串（如"sheetId!A1:B2"，单个单元格为"sheetId!A1:A1"）
     */
    public static String buildRange(String sheetId, int startRow, int startCol, int endRow, int endCol) {
        String startCell = convertToCellAddress(startRow, startCol);
        String endCell = convertToCellAddress(endRow, endCol);
        
        // 对于飞书v2 API，即使是单个单元格也需要使用开始:结束格式
        if (sheetId != null && !sheetId.isEmpty()) {
            return sheetId + "!" + startCell + ":" + endCell;
        } else {
            return startCell + ":" + endCell;
        }
    }
    
    /**
     * 将行列索引转换为A1表示法的单元格地址
     * 
     * @param row 行索引（1-based）
     * @param col 列索引（1-based）
     * @return A1表示法的单元格地址，如"A1", "B2"
     */
    public static String convertToCellAddress(int row, int col) {
        return getColumnLetter(col) + row;
    }
    
    /**
     * 将列索引转换为列字母
     * 
     * @param col 列索引（1-based）
     * @return 列字母，如"A", "B", "AA", "AB"
     */
    public static String getColumnLetter(int col) {
        StringBuilder sb = new StringBuilder();
        
        while (col > 0) {
            col--; // 调整为0开始的索引
            sb.insert(0, (char) ('A' + col % 26));
            col = col / 26;
        }
        
        return sb.toString();
    }
    
    /**
     * 将行列索引转换为A1表示法的单元格引用（0-based转1-based）
     * 
     * @param row 行索引（从0开始）
     * @param col 列索引（从0开始）
     * @return A1表示法的单元格引用，如"A1", "B2"
     */
    public static String getCellReference(int row, int col) {
        StringBuilder colRef = new StringBuilder();
        col++; // 转换为1-based索引
        while (col > 0) {
            col--;
            colRef.insert(0, (char) ('A' + col % 26));
            col /= 26;
        }
        return colRef.toString() + (row + 1); // 行也转换为1-based索引
    }
    
    /**
     * 构建完整范围字符串（使用0-based索引）
     * 
     * @param sheetId 工作表ID
     * @param rows 行数
     * @param cols 列数
     * @return 完整范围字符串，如"sheetId!A1:Z100"
     */
    public static String buildFullRange(String sheetId, int rows, int cols) {
        String endColumn = getColumnLetter(cols);
        String range = String.format("A1:%s%d", endColumn, rows);
        
        if (sheetId != null && !sheetId.isEmpty()) {
            return sheetId + "!" + range;
        }
        return range;
    }
    
    /**
     * 解析单元格ID，支持多种格式
     * 
     * @param cellId 单元格ID（可能是A1格式或"row,col"格式）
     * @return [row, col]数组（1-based），如果无法解析返回null
     */
    public static int[] parseCellId(String cellId) {
        if (cellId == null || cellId.isEmpty()) {
            return null;
        }
        
        // 检查是否是A1格式
        if (cellId.matches("[A-Z]+\\d+")) {
            // A1格式，需要解析
            int i = 0;
            while (i < cellId.length() && Character.isLetter(cellId.charAt(i))) {
                i++;
            }
            String colPart = cellId.substring(0, i);
            String rowPart = cellId.substring(i);
            
            try {
                int col = columnLetterToIndex(colPart);
                int row = Integer.parseInt(rowPart);
                return new int[]{row, col};
            } catch (NumberFormatException e) {
                logger.warn("无法解析单元格ID: {}", cellId);
                return null;
            }
        } else if (cellId.contains(",")) {
            // "row,col"格式
            String[] coords = cellId.split(",");
            if (coords.length == 2) {
                try {
                    int row = Integer.parseInt(coords[0].trim());
                    int col = Integer.parseInt(coords[1].trim());
                    return new int[]{row, col};
                } catch (NumberFormatException e) {
                    logger.warn("无法解析单元格ID: {}", cellId);
                    return null;
                }
            }
        }
        
        return null;
    }
    
    /**
     * 将列字母转换为列索引（1-based）
     * 
     * @param colLetter 列字母，如"A", "AA"
     * @return 列索引（1-based）
     */
    private static int columnLetterToIndex(String colLetter) {
        int index = 0;
        for (int i = 0; i < colLetter.length(); i++) {
            index = index * 26 + (colLetter.charAt(i) - 'A' + 1);
        }
        return index;
    }
    
    /**
     * 验证范围是否有效
     * 
     * @param startRow 起始行
     * @param startCol 起始列
     * @param endRow 结束行
     * @param endCol 结束列
     * @return true如果范围有效
     */
    public static boolean isValidRange(int startRow, int startCol, int endRow, int endCol) {
        return startRow > 0 && startCol > 0 && 
               endRow >= startRow && endCol >= startCol;
    }
    
    /**
     * 计算范围的单元格数量
     * 
     * @param startRow 起始行
     * @param startCol 起始列
     * @param endRow 结束行
     * @param endCol 结束列
     * @return 单元格数量
     */
    public static int calculateCellCount(int startRow, int startCol, int endRow, int endCol) {
        if (!isValidRange(startRow, startCol, endRow, endCol)) {
            return 0;
        }
        return (endRow - startRow + 1) * (endCol - startCol + 1);
    }
}